import os
import shutil
from random import random

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill
from openpyxl.utils import get_column_letter
from datetime import datetime, timedelta
from openpyxl.styles import Border, Side
import pymysql
from typing import Dict, List, Optional
from spiltExcel import split_excel_inputFile


# 在create_excel_report函数前新增数据库方法
def get_stock_sectors(type,sql):
    """
    获取股票行业板块信息（独立数据库方法）
    参数:
        stock_codes: 股票代码列表
    返回:
        字典{股票代码: 行业板块}
    """

    # 独立数据库配置（根据实际需要修改以下参数）
    db_config = {
        'host': '175.178.5.14',
        'port': 33066,
        'user': 'root',
        'password': '07M@Y0sqL1',
        'database': 'stock',
        'charset': 'utf8mb4',
        'connect_timeout': 10
    }

    sectors = {}
    try:
        conn = pymysql.connect(**db_config)
        with conn.cursor() as cursor:
            # 根据报告类型选择存储过程

            cursor.execute(sql)
            results = cursor.fetchall()
            # 定义列名
            if type == '1':
                columns = [
                    '名称', '周开盘价', '周收盘价', '成交额(亿)', '量比',
                    '本周涨幅(%)', '年度涨幅(%)', '行业板块'
                ]
            elif type == '2':
                columns = [
                    '板块名称', '板块市值', '上涨家数', '下跌家数', '板块涨幅',
                    '领涨股票', '领涨涨幅(%)'
                ]
            # 根据列名获取数据
            data = []
            for row in results:
                data.append(dict(zip(columns, row)))
            return data


    except Exception as e:
        print(f"数据库查询失败: {e}")
    finally:
        if 'conn' in locals() and conn:
            conn.close()


def getWeeklyStockTopN(start_date, end_date, size=100):
    wb = Workbook()
    ws = wb.active

    # 根据报告类型设置标题和文件名
    title_map = {
        1: '周涨幅_TOP100_个股盘点',
    }
    filename_map = {
        1: '周榜_TOP100_个股盘点',
    }

    # 设置全局字体
    font_header = Font(name='微软雅黑', bold=True, size=26)
    font_columns = Font(name='微软雅黑', size=24)
    fill_color = PatternFill(start_color='FFD966', end_color='FFD966', fill_type='solid')
    fill_white = PatternFill(start_color='FFFFFF', end_color='FFFFFF', fill_type='solid')  # 新增白色填充

    # 第一行表头（合并A-I）
    ws.merge_cells('A1:I1')
    ws['A1'] = title_map[1]
    ws['A1'].font = font_header
    ws['A1'].alignment = Alignment(horizontal='center', vertical='center')
    ws['A1'].fill = fill_white  # 添加白色背景

    # 第二行表头
    current_date = datetime.now().strftime("%Y%m%d")

    # 左侧合并A-C
    ws.merge_cells('A2:D2')
    ws['A2'] = f'数据日期：{start_date}至{end_date}'
    ws['A2'].font = font_header
    ws['A2'].alignment = Alignment(horizontal='left', vertical='center')  # 左对齐+垂直居中
    ws['A2'].fill = fill_white  # 添加白色背景

    # 右侧合并D-I
    ws.merge_cells('E2:I2')
    ws['E2'] = '数据仅供参考，不构成任何投资建议'
    ws['E2'].font = font_header
    ws['E2'].alignment = Alignment(horizontal='right', vertical='center')  # 右对齐+垂直居中
    ws['E2'].fill = fill_white  # 添加白色背景

    # 第三行列标题
    columns = [
        '序号', '名称', '周开盘价', '周收盘价', '成交额\n(亿)', '量比',
        '本周涨幅\n(%)', '年度涨幅\n(%)', '行业板块'
    ]

    # 添加边框样式（在所有方向添加细线边框）
    thin_border = Border(left=Side(style='thin'),
                         right=Side(style='thin'),
                         top=Side(style='thin'),
                         bottom=Side(style='thin'))

    for col, title in enumerate(columns, 1):
        cell = ws.cell(row=3, column=col, value=title)
        cell.fill = fill_color
        # 第三行列标题 加粗
        cell.font = Font(name='微软雅黑', bold=True, size=24)
        # 居中对齐并启用自动换行
        cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)  # 修改这里
        cell.border = thin_border  # 新增边框设置
        # 设置列宽自适应
        ws.column_dimensions[get_column_letter(col)].width = len(title) + 2

    # 设置自定义列宽（基于1厘米≈3.7个字符单位）
    column_widths = {
        'A': 12.88,  # 2cm
        'B': 30.65,  # 4.5cm
        'C': 25.65,  # 4.5cm
        'D': 20.47,  # 2.8cm
        'E': 20.88,  # 2.4cm
        'F': 20.47,  # 3.1cm
        'G': 30.65,  # 3.1cm
        'H': 18.47,  # 4.1cm
        'I': 30.87  # 5.1cm
    }

    for col, width in column_widths.items():
        ws.column_dimensions[col].width = width

    data = get_stock_sectors('1', f"CALL Get_Weekly_Stock_TOPN('{start_date}','{end_date}',{size})")

    # 修改数据写入逻辑（从第4行开始）
    for row_idx, item in enumerate(data, start=4):
        # 序号列（A列）也填充边框
        ws.cell(row=row_idx, column=1, value=row_idx - 3).alignment = Alignment(horizontal='center', vertical='center')
        ws.cell(row=row_idx, column=1).border = thin_border  # 新增边框设置]
        # 字体设为微软雅黑
        # 字体大小为18
        ws.cell(row=row_idx, column=1).font = font_columns
        columns = [
            '序号', '名称', '周开盘价', '周收盘价', '成交额\n(亿)', '量比',
            '本周涨幅\n(%)', '年度涨幅\n(%)', '行业板块'
        ]

        # 数据列（B-I列）
        columns_mapping = [
            ('名称', 2),  # B列
            ('周开盘价', 3),  # C列
            ('周收盘价', 4),  # D列
            ('成交额(亿)', 5),  # E列
            ('量比', 6),  # F列
            ('本周涨幅(%)', 7),  # G列
            ('年度涨幅(%)', 8),  # H列
            ('行业板块', 9)  # I列
        ]

        # 应用样式并写入数据
        for field, col in columns_mapping:
            cell = ws.cell(row=row_idx, column=col, value=item.get(field, ''))
            # B列加粗
            cell.font = font_columns

            if field == '名称':
                cell.font = Font(name='微软雅黑', bold=True, size=24)
            cell.alignment = Alignment(horizontal='center', vertical='center')
            cell.border = thin_border  # 添加边框

    # 保存文件 添加时间戳
    # 年月日时间戳
    dayMonthYear = datetime.now().strftime("%Y%m%d")
    # 确保目录存在
    inputFileUrl = f'../spiltExcel/input/excel/{dayMonthYear}/{filename_map[1]}_{dayMonthYear}.xlsx'
    os.makedirs(os.path.dirname(inputFileUrl), exist_ok=True)
    wb.save(inputFileUrl)
    print(f'{filename_map[1]}_{dayMonthYear}.xlsx文件已生成')
    print("开始生成截图")
    # 截图
    outputFileUrl = f'../spiltExcel/output/{dayMonthYear}/{filename_map[1]}/'
    split_excel_inputFile(inputFileUrl, outputFileUrl,'3')
    # 随机选择模板中的封面 D:\code\pythonCode\pythonProject\模板\images
    # 将封面复制到输出目录的images文件夹
    os.makedirs(os.path.join(outputFileUrl, 'images'), exist_ok=True)

    # 确保输出目录存在
    cover_dir = 'D:\\code\\pythonCode\\pythonProject\\模板\\images'
    cover_files = os.listdir(cover_dir)
    if cover_files:
        # 当前月的天数%4+1 取得后缀
        day = datetime.now().day
        suffix = str(day % 4 + 1)
        cover_file = f'周涨幅TOP100个股_1.jpg'
        cover_path = os.path.join(cover_dir, cover_file)
        shutil.copy(cover_path, os.path.join(outputFileUrl, 'images', f'cover_{suffix}.jpg'))
    print("封面复制完成")
    print("==================================================输出文本内容==================================================")
    dayMonth = datetime.now().strftime("%m.%d")
    # dayMonth去掉前缀的0
    dayMonth = dayMonth.lstrip('0')
    print(f"本笔记筛选本周个股涨幅Top100的个股，并给出其板块来源，年度涨幅等信息")
    print("ps：数据仅供参考，不构成投资建议")
    print("==================================================输出文本内容结束==================================================")


def GetSectorAnalysis(sector_type, start_date, end_date, size):
    wb = Workbook()
    ws = wb.active

    # 根据报告类型设置标题和文件名
    title_map = {
        1: '本周_概念板块_TOP50',
        2: '本周_行业板块_TOP30',

    }
    filename_map = {
        1: '本周_概念板块_涨幅TOP50',
        2: '本周_行业板块_涨幅TOP30',
    }

    # 设置全局字体
    font_header = Font(name='微软雅黑', bold=True, size=26)
    font_columns = Font(name='微软雅黑', size=24)
    fill_color = PatternFill(start_color='FFD966', end_color='FFD966', fill_type='solid')
    fill_white = PatternFill(start_color='FFFFFF', end_color='FFFFFF', fill_type='solid')  # 新增白色填充

    # 第一行表头（合并A-I）
    ws.merge_cells('A1:H1')
    ws['A1'] = title_map[1]
    ws['A1'].font = font_header
    ws['A1'].alignment = Alignment(horizontal='center', vertical='center')
    ws['A1'].fill = fill_white  # 添加白色背景

    # 第二行表头
    current_date = datetime.now().strftime("%Y%m%d")

    # 左侧合并A-C
    ws.merge_cells('A2:D2')
    ws['A2'] = f'数据日期：{start_date}至{end_date}'
    ws['A2'].font = font_header
    ws['A2'].alignment = Alignment(horizontal='left', vertical='center')  # 左对齐+垂直居中
    ws['A2'].fill = fill_white  # 添加白色背景

    # 右侧合并D-I
    ws.merge_cells('E2:H2')
    ws['E2'] = '数据仅供参考，不构成任何投资建议'
    ws['E2'].font = font_header
    ws['E2'].alignment = Alignment(horizontal='right', vertical='center')  # 右对齐+垂直居中
    ws['E2'].fill = fill_white  # 添加白色背景

    # 第三行列标题
    columns = [
        '序号', '板块名称', '板块市值', '上涨家数', '下跌家数',
        '板块涨幅\n(%)', '领涨股', '领涨涨幅\n(%)'
    ]

    # 添加边框样式（在所有方向添加细线边框）
    thin_border = Border(left=Side(style='thin'),
                         right=Side(style='thin'),
                         top=Side(style='thin'),
                         bottom=Side(style='thin'))

    for col, title in enumerate(columns, 1):
        cell = ws.cell(row=3, column=col, value=title)
        cell.fill = fill_color
        # 第三行列标题 加粗
        cell.font = Font(name='微软雅黑', bold=True, size=24)
        # 居中对齐并启用自动换行
        cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)  # 修改这里
        cell.border = thin_border  # 新增边框设置
        # 设置列宽自适应
        ws.column_dimensions[get_column_letter(col)].width = len(title) + 2

    # 设置自定义列宽（基于1厘米≈3.7个字符单位）
    column_widths = {
        'A': 12.88,  # 2cm
        'B': 30.65,  # 4.5cm
        'C': 25.65,  # 4.5cm
        'D': 20.47,  # 2.8cm
        'E': 20.88,  # 2.4cm
        'F': 20.47,  # 3.1cm
        'G': 30.65,  # 3.1cm
        'H': 18.47,  # 4.1cm
        'I': 30.87  # 5.1cm
    }

    for col, width in column_widths.items():
        ws.column_dimensions[col].width = width

    data = get_stock_sectors('2', f"CALL GetSectorAnalysis('{sector_type}',{size},'{start_date}','{end_date}')")

    # 修改数据写入逻辑（从第4行开始）
    for row_idx, item in enumerate(data, start=4):
        # 序号列（A列）也填充边框
        ws.cell(row=row_idx, column=1, value=row_idx - 3).alignment = Alignment(horizontal='center', vertical='center')
        ws.cell(row=row_idx, column=1).border = thin_border  # 新增边框设置]
        # 字体设为微软雅黑
        # 字体大小为18
        ws.cell(row=row_idx, column=1).font = font_columns

        # 数据列（B-I列）
        columns_mapping = [
            ('板块名称', 2),  # B列
            ('板块市值', 3),  # C列
            ('上涨家数', 4),  # D列
            ('下跌家数', 5),  # E列
            ('板块涨幅', 6),  # F列
            ('领涨股票', 7),  # G列
            ('领涨涨幅(%)', 8),  # H列
        ]

        # 应用样式并写入数据
        for field, col in columns_mapping:
            cell = ws.cell(row=row_idx, column=col, value=item.get(field, ''))
            # B列加粗
            cell.font = font_columns

            if field == '名称':
                cell.font = Font(name='微软雅黑', bold=True, size=24)
            cell.alignment = Alignment(horizontal='center', vertical='center')
            cell.border = thin_border  # 添加边框

    # 保存文件 添加时间戳
    # 年月日时间戳
    dayMonthYear = datetime.now().strftime("%Y%m%d")
    # 确保目录存在
    inputFileUrl = f'../spiltExcel/input/excel/{dayMonthYear}/{filename_map[1]}_{dayMonthYear}.xlsx'
    os.makedirs(os.path.dirname(inputFileUrl), exist_ok=True)
    wb.save(inputFileUrl)
    if sector_type == '1':
        print(f'{filename_map[1]}_{dayMonthYear}.xlsx文件已生成')
    else:
        print(f'{filename_map[2]}_{dayMonthYear}.xlsx文件已生成')
    print("开始生成截图")
    # 截图
    if sector_type == '1':
        outputFileUrl = f'../spiltExcel/output/{dayMonthYear}/{filename_map[1]}/'
    else:
        outputFileUrl = f'../spiltExcel/output/{dayMonthYear}/{filename_map[2]}/'
    split_excel_inputFile(inputFileUrl, outputFileUrl,'3')
    # 随机选择模板中的封面 D:\code\pythonCode\pythonProject\模板\images
    # 将封面复制到输出目录的images文件夹
    os.makedirs(os.path.join(outputFileUrl, 'images'), exist_ok=True)

    # 确保输出目录存在
    cover_dir = 'D:\\code\\pythonCode\\pythonProject\\模板\\images'
    cover_files = os.listdir(cover_dir)
    if cover_files:
        # 当前月的天数%4+1 取得后缀
        day = datetime.now().day
        suffix = str(day % 4 + 1)
        if sector_type == '1':
            cover_file = f'本周概念TOP50.jpg'
        else:
            cover_file = f'本周行业TOP20.jpg'
        cover_path = os.path.join(cover_dir, cover_file)
        shutil.copy(cover_path, os.path.join(outputFileUrl, 'images', f'cover_{suffix}.jpg'))
    print("封面复制完成")
    print("==================================================输出文本内容==================================================")
    dayMonth = datetime.now().strftime("%m.%d")
    # dayMonth去掉前缀的0
    dayMonth = dayMonth.lstrip('0')
    if sector_type == '1':
        print(f"本笔记统计本周概念板块涨幅Top50及领涨股票信息")
    else:
        print(f"本笔记统计本周行业板块涨幅Top20及领涨股票信息")
    print("ps：数据仅供参考，不构成投资建议")
    print("==================================================输出文本内容结束==================================================")



def process():
    main()


def main():
    # 获取本周一和周五日期
    # 获取本周一和周五日期
    today = datetime.now()
    # 本周一
    start_date = today - timedelta(days=today.weekday())
    # 本周五
    end_date = start_date + timedelta(days=4)
    # 格式化日期为字符串
    start_date_str = start_date.strftime('%Y-%m-%d')
    end_date_str = end_date.strftime('%Y-%m-%d')

    start_date_str = '2025-10-09'
    end_date_str = '2025-10-10'
    print(f"本周一：{start_date_str}，本周五：{end_date_str}")
    size = 100
    print("获取本周涨幅top100个股")
    getWeeklyStockTopN(start_date_str, end_date_str, size)
    print("获取概念板块top50")
    GetSectorAnalysis('1', start_date_str, end_date_str, 50)
    print("获取行业板块top20")
    GetSectorAnalysis('2', start_date_str, end_date_str, 20)


if __name__ == '__main__':
    main()
